package net.bplaced.streetfighter;

import java.util.ArrayList;
import java.util.List;

import net.bplaced.streetfighter.adapter.MainMenuEntryAdapter;
import net.bplaced.streetfighter.lib.async.task.TeamLoaderTask;
import net.bplaced.streetfighter.lib.async.task.UpdateCheckerTask;
import net.bplaced.streetfighter.lib.model.AppVersion;
import net.bplaced.streetfighter.lib.model.MainMenuEntry;
import net.bplaced.streetfighter.lib.model.Team;
import net.bplaced.streetfighter.lib.utils.CallBack;
import net.bplaced.streetfighter.lib.utils.MainMenuItemType;
import net.bplaced.streetfighter.lib.utils.RuntimeData;
import net.bplaced.streetfighter.lib.utils.RuntimeDataKey;
import net.bplaced.streetfighter.lib.utils.RuntimeDataObject;
import net.bplaced.streetfighter.lib.utils.ServiceReturnPackage;
import net.bplaced.streetfighter.utils.update.CrashManager;
import net.bplaced.streetfighter.utils.update.UpdateActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.Toast;

/**
 * Provides an {@link Activity} for the main menu.
 * 
 * @author Sebastian Hoffmann <bo.hoffi@googlemail.com>
 */
public class MainActivity
        extends Activity {

    private static final String APP_IDENTIFIER = "app_streetfighter4";

    /**
     * Called when the activity is first created. Create the available menu entries and render them in a
     * {@link GridView}.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.setContentView(R.layout.main_grid);

        UpdateActivity.iconDrawableId = R.drawable.ic_launcher;

        final List<MainMenuEntry> menuEntries = this.createMenuEntries();
        final MainMenuEntryAdapter entryAdapter = new MainMenuEntryAdapter(this, menuEntries);
        final GridView grid = (GridView) this.findViewById(R.id.main_grid_grid);
        grid.setAdapter(entryAdapter);
        grid.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                final MainMenuEntry e = (MainMenuEntry) view.getTag();

                if (e.getItemType() == MainMenuItemType.INTENT) {

                    MainActivity.this.startActivity(e.getEntryIntent());

                } else if (e.getItemType() == MainMenuItemType.UPDATE_TASK) {

                    MainActivity.this.checkForUpdates();
                }
            }
        });

        if (RuntimeData.getInstance().get(RuntimeDataKey.HOME_TEAM) == null) {

            final TeamLoaderTask task =
                    new TeamLoaderTask(this, this.getResources().getString(R.string.menu_progress_message),
                            this.onFinishedLoading);
            task.execute(this.getResources().getString(R.string.home_team));
        }
    }

    @Override
    protected void onResume() {

        this.checkForCrashes();
        super.onResume();
    }

    /**
     * Deklariert einen Callback, welcher zum Ende des Serviceaurufes aufgerufen wird.
     */
    private final CallBack<ServiceReturnPackage<Team[]>> onFinishedLoading =
            new CallBack<ServiceReturnPackage<Team[]>>() {

                @Override
                public void callbackAction(ServiceReturnPackage<Team[]> result) {

                    if (result != null) {
                        if (result.getContent() != null) {

                            final Team homeTeam = result.getContent()[0];
                            RuntimeData.getInstance().put(RuntimeDataKey.HOME_TEAM,
                                    new RuntimeDataObject<Team>(homeTeam));

                        } else {

                            Toast.makeText(MainActivity.this, result.getErrorMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
                };
            };

    /**
     * Deklariert einen Callback, welcher zum Ende des Serviceaurufes aufgerufen wird.
     */
    private final CallBack<ServiceReturnPackage<AppVersion[]>> onFinishedUpdateCheck =
            new CallBack<ServiceReturnPackage<AppVersion[]>>() {

                @Override
                public void callbackAction(ServiceReturnPackage<AppVersion[]> result) {

                    if (result != null) {
                        if (result.getContent() != null) {

                            MainActivity.this.compareVersions(result.getContent());

                        } else {

                            Toast.makeText(MainActivity.this, result.getErrorMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
                };
            };

    private void compareVersions(AppVersion[] versions) {

        Integer versionCode = 0;

        try {
            versionCode =
                    MainActivity.this.getPackageManager().getPackageInfo(MainActivity.this.getPackageName(),
                            PackageManager.GET_META_DATA).versionCode;

            RuntimeData.getInstance().put(RuntimeDataKey.CURRENT_VERSION, new RuntimeDataObject<Integer>(versionCode));

            if (versionCode < versions[0].versionCode) {
                RuntimeData.getInstance().put(RuntimeDataKey.UPDATES, new RuntimeDataObject<AppVersion[]>(versions));
                this.showDialog(versions);
            } else {
                this.showNoUpdateDialog();
            }

        } catch (final NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void showNoUpdateDialog() {

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.no_update_dialog_title);
        builder.setMessage(R.string.no_update_dialog_message);

        builder.setPositiveButton(R.string.no_update_dialog_positive_button, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });

        builder.create().show();
    }

    private void showDialog(final AppVersion[] versions) {

        if (this.isFinishing()) {
            return;
        }

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.update_dialog_title);
        builder.setMessage(R.string.update_dialog_message);

        builder.setNegativeButton(R.string.update_dialog_negative_button, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });

        builder.setPositiveButton(R.string.update_dialog_positive_button, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                final Intent intent = new Intent(MainActivity.this, UpdateActivity.class);
                MainActivity.this.startActivity(intent);
            }
        });

        builder.create().show();
    }

    /**
     * Checks for an available update of the app.
     */
    private void checkForUpdates() {

        final UpdateCheckerTask task =
                new UpdateCheckerTask(this, this.getResources().getString(R.string.menu_update_progress_message),
                        this.onFinishedUpdateCheck);
        task.execute(MainActivity.APP_IDENTIFIER);
    }

    /**
     * Checks for previous app crashes.
     */
    private void checkForCrashes() {

        CrashManager.register(this, "http://streetfighter.bplaced.net/app/", "net.bplaced.streetfighter");
    }

    /**
     * Creates a {@link List<?>} of {@link MainMenuEntry} for rendering the main menu.
     * 
     * @return {@link List<?>} of {@link MainMenuEntry}
     */
    private List<MainMenuEntry> createMenuEntries() {

        final List<MainMenuEntry> entries = new ArrayList<MainMenuEntry>();

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_matches), new Intent(this,
                MatchesActivity.class), MainMenuItemType.INTENT, R.drawable.calendar, true));

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_table), new Intent(this,
                TableActivity.class), MainMenuItemType.INTENT, R.drawable.table, true));

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_goalGetter), new Intent(this,
                GoalGetterActivity.class), MainMenuItemType.INTENT, R.drawable.goal, true));

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_guestbook), new Intent(this,
                GuestbookActivity.class), MainMenuItemType.INTENT, R.drawable.guestbook, true));

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_check_updates), null,
                MainMenuItemType.UPDATE_TASK, R.drawable.refresh, true));

        entries.add(new MainMenuEntry(this.getResources().getString(R.string.menu_help), new Intent(this,
                HelpActivity.class), MainMenuItemType.INTENT, R.drawable.help, true));

        return entries;
    }
}